<template>
  <div class="drone-control-container">
    <div class="main-content">
      <!-- 视频流区域 -->
      <div class="video-section">
        <div class="video-container">
          <img
            v-if="isConnected"
            :src="videoFeedUrl"
            alt="无人机视频流"
            class="video-feed"
            @error="handleVideoError"
          />
          <div v-else class="video-placeholder">
            <CameraOutlined class="placeholder-icon" />
            <p>请连接无人机以查看视频流</p>
          </div>
        </div>
      </div>

      <!-- 飞行控制区域 -->
      <div class="flight-controls">
        <h2>飞行控制</h2>

        <!-- 连接控制 -->
        <div class="connection-controls">
          <button @click="connectDrone" :disabled="isConnected || connecting" class="connect-btn">
            <RocketOutlined />
            <span>{{ connecting ? '连接中...' : '连接无人机' }}</span>
          </button>
          <button @click="disconnectDrone" :disabled="!isConnected" class="disconnect-btn">
            <DisconnectOutlined />
            <span>断开连接</span>
          </button>
        </div>

        <!-- 基础控制 -->
        <div class="basic-controls">
          <button
            @click="takeoff"
            :disabled="!isConnected || commandLoading"
            class="control-btn takeoff-btn"
          >
            <ArrowUpOutlined />
            <span>起飞</span>
          </button>
          <button
            @click="land"
            :disabled="!isConnected || commandLoading"
            class="control-btn land-btn"
          >
            <ArrowDownOutlined />
            <span>降落</span>
          </button>
          <button @click="emergency" :disabled="!isConnected" class="control-btn emergency-btn">
            <StopOutlined />
            <span>紧急停止</span>
          </button>

          <button @click="takePhoto" :disabled="!isConnected" class="control-btn photo-btn">
            <CameraOutlined />
            <span>拍照</span>
          </button>
          <button
            @click="isRecording ? stopRecording() : startRecording()"
            :disabled="!isConnected"
            :class="['control-btn', isRecording ? 'stop-record-btn' : 'record-btn']"
          >
            <VideoCameraOutlined v-if="!isRecording" />
            <StopOutlined v-if="isRecording" />
            <span>{{ isRecording ? '停止录像' : '开始录像' }}</span>
          </button>
        </div>

        <!-- 方向控制 -->
        <div class="direction-controls">
          <div class="control-pad">
            <button @click="startMove('forward')" @keyup="stopMove" class="dir-btn up-btn">
              <ArrowUpOutlined />
            </button>
            <div class="middle-row">
              <button @click="startMove('left')" @keyup="stopMove" class="dir-btn left-btn">
                <ArrowLeftOutlined />
              </button>
              <button @click="startMove('right')" @keyup="stopMove" class="dir-btn right-btn">
                <ArrowRightOutlined />
              </button>
            </div>
            <button @click="startMove('backward')" @keyup="stopMove" class="dir-btn down-btn">
              <ArrowDownOutlined />
            </button>
          </div>

          <div class="rotation-controls">
            <button
              @click="startMove('rotate_left')"
              @keyup="stopMove"
              class="rot-btn left-rot-btn"
            >
              <UndoOutlined />
              <span>左转</span>
            </button>
            <button @click="startMove('up')" @keyup="stopMove" class="rot-btn up-btn">
              <ArrowUpOutlined />
              <span>上升</span>
            </button>
            <button @click="startMove('down')" @keyup="stopMove" class="rot-btn down-btn">
              <ArrowDownOutlined />
              <span>下降</span>
            </button>
            <button
              @click="startMove('rotate_right')"
              @keyup="stopMove"
              class="rot-btn right-rot-btn"
            >
              <RedoOutlined />
              <span>右转</span>
            </button>
          </div>
        </div>

        <!-- 新增手柄状态显示区域 -->
        <div class="controller-status" v-if="gamepadConnected">
          <h3>手柄控制</h3>
          <div>已连接手柄: {{ gamepadName }}</div>
          <div>左摇杆: X: {{ leftStickX.toFixed(2) }}, Y: {{ leftStickY.toFixed(2) }}</div>
          <div>右摇杆: X: {{ rightStickX.toFixed(2) }}, Y: {{ rightStickY.toFixed(2) }}</div>
          <div class="controller-hints">
            <p>左摇杆: 前后左右移动</p>
            <p>右摇杆: 旋转和升降</p>
            <p>A键: 起飞</p>
            <p>B键: 降落</p>
            <p>X键: 拍照</p>
            <p>Y键: 切换录像</p>
            <p>BACK键: 紧急停止</p>
          </div>
        </div>
        <div class="controller-status" v-else>
          <h3>手柄控制</h3>
          <p>未检测到游戏手柄，请连接手柄后重试</p>
        </div>

        <!-- 键盘控制说明 -->
        <div class="keyboard-hints">
          <h3>键盘控制</h3>
          <div class="keyboard-layout">
            <div>WASD: 上下左右移动</div>
            <div>方向键: 前后左右飞行</div>
            <div>空格键: 起飞</div>
            <div>ESC: 降落</div>
          </div>
        </div>

        <div class="header">
          <h1>无人机控制系统</h1>
          <div class="connection-status">
            <span class="status-icon">
              <WifiOutlined v-if="isConnected" class="connected" />
              <DisconnectOutlined v-else class="disconnected" />
            </span>
            <span class="status-text">{{ isConnected ? '已连接' : '未连接' }}</span>
            <span class="battery-status" v-if="batteryLevel !== null">
              电池: {{ batteryLevel }}%
              <span :class="['battery-indicator', getBatteryColor(batteryLevel)]"></span>
            </span>
          </div>
        </div>
        <!-- 状态消息 -->
        <div class="status-bar">
          <div :class="['status-message', getStatusType()]">
            {{ statusMessage }}
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue'
import { message } from 'ant-design-vue'
import axios from 'axios'
import {
  WifiOutlined,
  DisconnectOutlined,
  RocketOutlined,
  StopOutlined,
  CameraOutlined,
  VideoCameraOutlined,
  ArrowUpOutlined,
  ArrowDownOutlined,
  ArrowLeftOutlined,
  ArrowRightOutlined,
  RedoOutlined,
  UndoOutlined,
} from '@ant-design/icons-vue'

// 配置axios基础URL，明确指向localhost:5000
const droneAxios = axios.create({
  baseURL: 'http://localhost:5000',
})
//axios.defaults.baseURL = 'http://localhost:5000'

// 响应式数据
const isConnected = ref(false)
const connecting = ref(false)
const commandLoading = ref(false)
const isRecording = ref(false)
const batteryLevel = ref(null)
const statusMessage = ref('系统准备就绪')
const videoFeedUrl = ref('http://localhost:5000/video_feed')
const gamepadConnected = ref(false)
const gamepadName = ref('')
const leftStickX = ref(0)
const leftStickY = ref(0)
const rightStickX = ref(0)
const rightStickY = ref(0)
const gamepadInterval = ref(null)
const stickDeadzone = 0.2 // 摇杆死区，防止微小移动被识别
const keyDebounceTimer = ref<NodeJS.Timeout | null>(null) // 键盘防抖定时器
const lastMoveCommand = ref('stop') // 记录上一次移动命令（去重用）

// 电池检查定时器
let batteryTimer: any = null

// 更新状态消息
const updateStatus = (msg: string, type = 'info') => {
  statusMessage.value = msg
  console.log('状态:', msg)

  // 使用Ant Design的message组件显示通知
  if (type === 'success') {
    message.success(msg)
  } else if (type === 'error') {
    message.error(msg)
  } else if (type === 'warning') {
    message.warning(msg)
  } else {
    message.info(msg)
  }
}

// 发送命令到后端
const sendCommand = async (endpoint: string, data = {}) => {
  try {
    commandLoading.value = true
    const response = await droneAxios.post(endpoint, data)

    if (response.data.status === 'success') {
      updateStatus(response.data.message, 'success')
    } else {
      updateStatus(response.data.message, 'error')
    }

    return response.data
  } catch (error) {
    if (droneAxios.isAxiosError(error)) {
      if (error.response) {
        updateStatus(`服务器错误: ${error.response.data.message || error.message}`, 'error')
      } else if (error.request) {
        updateStatus('网络错误: 无法连接到服务器', 'error')
      } else {
        updateStatus('请求错误: ' + error.message, 'error')
      }
    } else {
      updateStatus('未知错误: ' + error, 'error')
    }
    console.error('请求错误:', error)
    return { status: 'error', message: '请求失败' }
  } finally {
    commandLoading.value = false
  }
}

// 连接无人机
const connectDrone = async () => {
  connecting.value = true
  try {
    const result = await sendCommand('/connect_drone')
    if (result && result.status === 'success') {
      isConnected.value = true
      // 刷新视频流，确保使用正确的URL
      videoFeedUrl.value = 'http://localhost:5000/video_feed?' + new Date().getTime()
      // 开始定期检查电量
      startBatteryCheck()
    }
  } finally {
    connecting.value = false
  }
}

// 断开连接
const disconnectDrone = async () => {
  const result = await sendCommand('/disconnect_drone')
  if (result && result.status === 'success') {
    isConnected.value = false
    isRecording.value = false
    batteryLevel.value = null
    stopBatteryCheck()
  }
}

// 起飞
const takeoff = async () => {
  if (!isConnected.value) {
    updateStatus('请先连接无人机', 'warning')
    return
  }
  await sendCommand('/control', { command: 'takeoff' })
}

// 降落
const land = async () => {
  if (!isConnected.value) {
    updateStatus('请先连接无人机', 'warning')
    return
  }
  await sendCommand('/control', { command: 'land' })
}

// 紧急停止
const emergency = async () => {
  if (!isConnected.value) {
    updateStatus('请先连接无人机', 'warning')
    return
  }
  await sendCommand('/control', { command: 'emergency' })
}

// 拍照
const takePhoto = async () => {
  if (!isConnected.value) {
    updateStatus('请先连接无人机', 'warning')
    return
  }
  await sendCommand('/take_photo')
}

// 开始录像
const startRecording = async () => {
  if (!isConnected.value) {
    updateStatus('请先连接无人机', 'warning')
    return
  }
  if (isRecording.value) {
    updateStatus('已经在录像中', 'warning')
    return
  }
  const result = await sendCommand('/start_recording')
  if (result && result.status === 'success') {
    isRecording.value = true
  }
}

// 停止录像
const stopRecording = async () => {
  if (!isConnected.value) {
    updateStatus('请先连接无人机', 'warning')
    return
  }
  if (!isRecording.value) {
    updateStatus('没有在录像中', 'warning')
    return
  }
  const result = await sendCommand('/stop_recording')
  if (result && result.status === 'success') {
    isRecording.value = false
  }
}

// 获取电池电量
const getBattery = async () => {
  // 若未连接无人机，不执行后续逻辑
  if (!isConnected.value) {
    return;
  }

  try {
    // 发送请求获取电池电量
    const response = await droneAxios.get('/battery');

    if (response.data.status === 'success') {
      const currentBattery = response.data.battery;
      // 首次获取电量时直接更新并弹窗
      if (batteryLevel.value === null) {
        batteryLevel.value = currentBattery;
        updateStatus(`电池电量为${currentBattery}%`, 'success');
      }
      // 非首次获取时，仅当电量变化超过5%才弹窗（避免频繁提示）
      else if (Math.abs(currentBattery - batteryLevel.value) >= 5) {
        batteryLevel.value = currentBattery;
        updateStatus(`电池电量为${currentBattery}%`, 'success');
      }
      // 电量变化小于5%时，仅更新数值不弹窗
      else {
        batteryLevel.value = currentBattery;
      }

      // 低电量警告（电量≤20%时强制弹窗提醒）
      if (currentBattery <= 20 && currentBattery !== batteryLevel.value) {
        updateStatus(`警告：电池电量低（${currentBattery}%），请及时返航`, 'warning');
      }
    } else {
      // 后端返回失败状态时提示错误
      updateStatus(`获取电量失败：${response.data.message}`, 'error');
    }
  } catch (error) {
    // 网络请求失败时捕获错误
    console.error('获取电池电量出错:', error);
    updateStatus('获取电量失败，请检查网络连接', 'error');
  }
};

// 开始移动
const startMove = async (direction: string) => {
  if (!isConnected.value) {
    updateStatus('请先连接无人机', 'warning')
    return
  }
  await sendCommand('/control', {
    command: 'move',
    direction: direction,
  })
}

// 停止移动
const stopMove = async () => {
  if (isConnected.value) {
    await sendCommand('/control', {
      command: 'move',
      direction: 'stop',
    })
  }
}

// 电池检查相关函数
const startBatteryCheck = () => {
  batteryTimer = setInterval(getBattery, 10000) // 每10秒检查一次
}

const stopBatteryCheck = () => {
  if (batteryTimer) {
    clearInterval(batteryTimer)
    batteryTimer = null
  }
}

// 获取电池颜色
const getBatteryColor = (level: number) => {
  if (level > 50) return 'green'
  if (level > 20) return 'orange'
  return 'red'
}

// 获取状态类型
const getStatusType = () => {
  if (statusMessage.value.includes('成功')) return 'success'
  if (statusMessage.value.includes('错误') || statusMessage.value.includes('失败')) return 'error'
  if (statusMessage.value.includes('警告')) return 'warning'
  return 'info'
}

// 处理视频错误
const handleVideoError = () => {
  console.log('视频流加载错误')
  updateStatus('视频流加载失败，尝试重新连接...', 'warning')
  // 尝试重新连接视频流
  if (isConnected.value) {
    videoFeedUrl.value = 'http://localhost:5000/video_feed?' + new Date().getTime()
  }
}

// 键盘事件处理
const handleKeyDown = (e: KeyboardEvent) => {
  // 若未连接无人机，直接提示并返回
  if (!isConnected.value) {
    updateStatus('请先连接无人机', 'warning')
    return
  }

  // 清除上一次的按键防抖定时器，避免重复触发
  if (keyDebounceTimer.value) {
    clearTimeout(keyDebounceTimer.value)
  }

  let direction = 'stop'
  // 根据按键映射移动方向
  switch (e.key) {
    case 'ArrowUp':
      direction = 'forward' // 上箭头：向前
      break
    case 'ArrowDown':
      direction = 'backward' // 下箭头：向后
      break
    case 'ArrowLeft':
      direction = 'left' // 左箭头：向左
      break
    case 'ArrowRight':
      direction = 'right' // 右箭头：向右
      break
    case 'w':
    case 'W':
      direction = 'up' // W键：上升
      break
    case 's':
    case 'S':
      direction = 'down' // S键：下降
      break
    case 'a':
    case 'A':
      direction = 'rotate_left' // A键：向左旋转
      break
    case 'd':
    case 'D':
      direction = 'rotate_right' // D键：向右旋转
      break
    case ' ':
      takeoff() // 空格键：起飞（不参与防抖）
      return
    case 'Escape':
      land() // ESC键：降落（不参与防抖）
      return
    default:
      return // 其他按键不处理
  }

  // 防抖处理：50ms内连续按键仅触发一次命令
  keyDebounceTimer.value = setTimeout(() => {
    // 仅当当前命令与上一次不同时，才发送请求（去重）
    if (direction !== lastMoveCommand.value) {
      startMove(direction)
      lastMoveCommand.value = direction // 更新上一次命令状态
    }
  }, 50)

  e.preventDefault() // 阻止按键默认行为（如页面滚动）
}

const handleKeyUp = (e: KeyboardEvent) => {
  // 仅在无人机已连接时处理
  if (!isConnected.value) return;

  // 清除未执行的键盘防抖定时器（避免松开后仍发送命令）
  if (keyDebounceTimer.value) {
    clearTimeout(keyDebounceTimer.value);
    keyDebounceTimer.value = null;
  }

  // 仅当最后一次命令不是"stop"时，才发送停止命令（避免重复触发弹窗）
  if (lastMoveCommand.value !== 'stop') {
    stopMove(); // 发送停止命令到后端
    lastMoveCommand.value = 'stop'; // 更新命令状态为停止
  }

  // 阻止按键默认行为（如页面滚动等）
  e.preventDefault();
};

// 新增游戏手柄处理函数
const handleGamepad = () => {
  const gamepads = navigator.getGamepads()
  let activeGamepad = null

  // 查找第一个连接的游戏手柄
  for (let i = 0; i < gamepads.length; i++) {
    if (gamepads[i]) {
      activeGamepad = gamepads[i]
      break
    }
  }

  if (!activeGamepad) {
    gamepadConnected.value = false
    gamepadName.value = ''
    // 手柄断开时，发送一次stop命令（避免无人机持续移动）
    if (lastMoveCommand.value !== 'stop' && isConnected.value) {
      stopMove()
      lastMoveCommand.value = 'stop'
    }
    return
  }

  gamepadConnected.value = true
  gamepadName.value = activeGamepad.id

  // 处理摇杆输入（标准化到-1到1范围）
  // 左摇杆 - 前后左右移动
  leftStickX.value = activeGamepad.axes[0]
  leftStickY.value = activeGamepad.axes[1]

  // 右摇杆 - 旋转和升降
  rightStickX.value = activeGamepad.axes[2]
  rightStickY.value = activeGamepad.axes[3]

  // 处理按键
  // A键 - 起飞 (通常是按钮0)
  if (activeGamepad.buttons[0].pressed) {
    takeoff()
  }

  // B键 - 降落 (通常是按钮1)
  if (activeGamepad.buttons[1].pressed) {
    land()
  }

  // X键 - 拍照 (通常是按钮2)
  if (activeGamepad.buttons[2].pressed) {
    takePhoto()
  }

  // Y键 - 切换录像 (通常是按钮3)
  if (activeGamepad.buttons[3].pressed) {
    isRecording.value ? stopRecording() : startRecording()
  }

  // BACK键 - 紧急停止 (通常是按钮8)
  if (activeGamepad.buttons[8].pressed) {
    emergency()
  }

  if (isConnected.value) {
    let direction = 'stop'
    // 左摇杆 - 前后左右
    if (Math.abs(leftStickY.value) > stickDeadzone) {
      direction = leftStickY.value < 0 ? 'forward' : 'backward'
    } else if (Math.abs(leftStickX.value) > stickDeadzone) {
      direction = leftStickX.value < 0 ? 'left' : 'right'
    }
    // 右摇杆 - 旋转和升降
    else if (Math.abs(rightStickY.value) > stickDeadzone) {
      direction = rightStickY.value < 0 ? 'up' : 'down'
    } else if (Math.abs(rightStickX.value) > stickDeadzone) {
      direction = rightStickX.value < 0 ? 'rotate_left' : 'rotate_right'
    }

    // 仅当当前命令与上一次不同时，才发送请求
    if (direction !== lastMoveCommand.value) {
      if (direction === 'stop') {
        stopMove()
      } else {
        startMove(direction)
      }
      lastMoveCommand.value = direction // 更新上一次命令
    }
  }
}

// 启动游戏手柄监听
const startGamepadMonitoring = () => {
  if (!gamepadInterval.value) {
    // 每50ms检查一次手柄状态
    gamepadInterval.value = setInterval(handleGamepad, 100)
  }
}

// 停止游戏手柄监听
const stopGamepadMonitoring = () => {
  if (gamepadInterval.value) {
    clearInterval(gamepadInterval.value)
    gamepadInterval.value = null
  }
}

// 生命周期钩子
onMounted(() => {
  // 键盘事件绑定（仅一次）
  document.addEventListener('keydown', handleKeyDown)
  document.addEventListener('keyup', handleKeyUp)
  updateStatus('Vue控制界面已加载', 'success')

  // 手柄事件监听（仅一次）
  window.addEventListener('gamepadconnected', (e) => {
    updateStatus(`游戏手柄已连接: ${e.gamepad.id}`, 'success')
    startGamepadMonitoring()
  })
  window.addEventListener('gamepaddisconnected', (e) => {
    updateStatus(`游戏手柄已断开: ${e.gamepad.id}`, 'warning')
    gamepadConnected.value = false
    stopGamepadMonitoring() // 断开时停止监听，避免无效请求
  })

  // 初始检查手柄（仅一次）
  startGamepadMonitoring()
})

onUnmounted(() => {
  // 清理所有事件，避免内存泄漏
  document.removeEventListener('keydown', handleKeyDown)
  document.removeEventListener('keyup', handleKeyUp)
  window.removeEventListener('gamepadconnected', () => {})
  window.removeEventListener('gamepaddisconnected', () => {})
  stopBatteryCheck()
  stopGamepadMonitoring()
})
</script>

<style scoped>
.drone-control-container {
  display: flex;
  flex-direction: column;
  background: linear-gradient(135deg, #fffacd 0%, #add8e6 100%);
  color: white;
}

.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin: 16px 0;
  padding: 20px;
  background: rgba(0, 0, 0, 0.1);
  backdrop-filter: blur(10px);
  border-radius: 10px;
}

.header h1 {
  margin: 0;
  font-size: 24px;
  font-weight: 600;
}

.connection-status {
  display: flex;
  align-items: center;
  gap: 15px;
}

.status-icon {
  font-size: 20px;
}

.status-icon .connected {
  color: #52c41a;
}

.status-icon .disconnected {
  color: #ff4d4f;
}

.battery-status {
  display: flex;
  align-items: center;
  gap: 5px;
}

.battery-indicator {
  width: 12px;
  height: 12px;
  border-radius: 50%;
}

.battery-indicator.green {
  background-color: #52c41a;
}

.battery-indicator.orange {
  background-color: #faad14;
}

.battery-indicator.red {
  background-color: #ff4d4f;
}

.main-content {
  display: flex;
  flex: 1;
  padding: 20px;
  gap: 20px;
}

.video-section {
  flex: 2;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.video-container {
  flex: 1;
  background: rgba(0, 0, 0, 0.3);
  border-radius: 15px;
  overflow: hidden;
  position: relative;
  min-height: 400px;
}

.video-feed {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.video-placeholder {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 15px;
  color: #ccc;
}

.placeholder-icon {
  font-size: 64px;
  opacity: 0.5;
}

.video-controls {
  display: flex;
  gap: 10px;
  justify-content: center;
}

.flight-controls {
  flex: 1;
  background: rgba(0, 0, 0, 0.2);
  border-radius: 15px;
  padding: 20px;
  backdrop-filter: blur(10px);
}

.flight-controls h2 {
  margin-top: 0;
  color: #fff;
  text-align: center;
  margin-bottom: 20px;
}

.connection-controls {
  display: flex;
  gap: 10px;
  margin-bottom: 20px;
  justify-content: center;
}

.basic-controls {
  display: flex;
  gap: 10px;
  margin-bottom: 20px;
  justify-content: center;
}

.direction-controls {
  display: flex;
  flex-direction: column;
  gap: 20px;
  margin-bottom: 20px;
}

.control-pad {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
}

.middle-row {
  display: flex;
  gap: 105px;
}

.rotation-controls {
  display: flex;
  justify-content: center;
  gap: 10px;
  flex-wrap: wrap;
}

.control-btn,
.connect-btn,
.disconnect-btn,
.dir-btn,
.rot-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 12px 20px;
  border: none;
  border-radius: 8px;
  cursor: pointer;
  font-size: 14px;
  font-weight: 500;
  transition: all 0.2s ease;
  color: white;
}

.control-btn:disabled,
.connect-btn:disabled,
.disconnect-btn:disabled,
.dir-btn:disabled,
.rot-btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.connect-btn {
  background: linear-gradient(45deg, #52c41a, #389e0d);
}

.connect-btn:hover:not(:disabled) {
  background: linear-gradient(45deg, #73d13d, #52c41a);
}

.disconnect-btn {
  background: linear-gradient(45deg, #ff4d4f, #cf1322);
}

.disconnect-btn:hover:not(:disabled) {
  background: linear-gradient(45deg, #ff7875, #ff4d4f);
}

.takeoff-btn {
  background: linear-gradient(45deg, #1890ff, #096dd9);
}

.takeoff-btn:hover:not(:disabled) {
  background: linear-gradient(45deg, #40a9ff, #1890ff);
}

.land-btn {
  background: linear-gradient(45deg, #faad14, #d46b08);
}

.land-btn:hover:not(:disabled) {
  background: linear-gradient(45deg, #ffc53d, #faad14);
}

.emergency-btn {
  background: linear-gradient(45deg, #ff4d4f, #cf1322);
}

.emergency-btn:hover:not(:disabled) {
  background: linear-gradient(45deg, #ff7875, #ff4d4f);
}

.photo-btn {
  background: linear-gradient(45deg, #722ed1, #531dab);
}

.photo-btn:hover:not(:disabled) {
  background: linear-gradient(45deg, #9254de, #722ed1);
}

.record-btn {
  background: linear-gradient(45deg, #ff4d4f, #cf1322);
}

.record-btn:hover:not(:disabled) {
  background: linear-gradient(45deg, #ff7875, #ff4d4f);
}

.stop-record-btn {
  background: linear-gradient(45deg, #faad14, #d46b08);
}

.stop-record-btn:hover:not(:disabled) {
  background: linear-gradient(45deg, #ffc53d, #faad14);
}

.dir-btn {
  width: 50px;
  height: 50px;
  background: rgba(255, 255, 255, 0.2);
  border-radius: 50%;
  font-size: 18px;
}

.dir-btn:hover:not(:disabled) {
  background: rgba(255, 255, 255, 0.3);
}

.rot-btn {
  background: rgba(255, 255, 255, 0.2);
  padding: 8px 15px;
}

.rot-btn:hover:not(:disabled) {
  background: rgba(255, 255, 255, 0.3);
}

.keyboard-hints {
  background: rgba(0, 0, 0, 0.3);
  border-radius: 10px;
  padding: 15px;
  margin-top: 20px;
}

.keyboard-hints h3 {
  margin-top: 0;
  margin-bottom: 10px;
  color: #fff;
  font-size: 16px;
}

.keyboard-layout {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 5px;
  font-size: 14px;
  color: #ccc;
}

.status-bar {
  padding: 15px 20px;
}

.status-message {
  padding: 8px 16px;
  border-radius: 20px;
  font-size: 14px;
  font-weight: 500;
  text-align: center;
}

.status-message.success {
  background: rgba(82, 196, 26, 0.2);
  color: #52c41a;
}

.status-message.error {
  background: rgba(255, 77, 79, 0.2);
  color: #ff4d4f;
}

.status-message.warning {
  background: rgba(250, 173, 20, 0.2);
  color: #faad14;
}

.status-message.info {
  background: rgba(24, 144, 255, 0.2);
  color: #1890ff;
}

@media (max-width: 768px) {
  .main-content {
    flex-direction: column;
  }

  .header {
    flex-direction: column;
    gap: 10px;
  }

  .connection-status {
    flex-wrap: wrap;
    justify-content: center;
  }

  .video-container {
    min-height: 250px;
  }
}

.controller-status {
  background: rgba(0, 0, 0, 0.3);
  border-radius: 10px;
  padding: 15px;
  margin-top: 20px;
  color: #fff;
}

.controller-status h3 {
  margin-top: 0;
  margin-bottom: 10px;
  font-size: 16px;
}

.controller-hints {
  margin-top: 10px;
  font-size: 14px;
  color: #ccc;
}

.controller-hints p {
  margin: 5px 0;
}
</style>
